package ip

import (
	mysqldao "ahutoj/web/dao/mysqlDao"
	"ahutoj/web/utils"
	"context"
	"os"
)

// IP struct
type IP struct {
	ProxyId       int64  `gorm:"primary_key; auto_increment; not null" json:"-"`
	ProxyHost     string `gorm:"type:varchar(255); not null; unique" json:"proxyHost"`
	ProxyPort     int    `gorm:"type:int(11); not null" json:"proxyPort"`
	ProxyType     string `gorm:"type:varchar(64); not null" json:"proxyType"`
	ProxyLocation string `gorm:"type:varchar(255); default null" json:"proxyLocation"`
	ProxySpeed    int    `gorm:"type:int(20); not null; default 0" json:"proxySpeed"`
	ProxySource   string `gorm:"type:varchar(64); not null;" json:"proxySource"`
	CreateTime    string `gorm:"type:varchar(50); not null" json:"-"`
	UpdateTime    string `gorm:"type:varchar(50); default ''" json:"updateTime"`
}

func InitIpTable(ctx context.Context) {
	logger := utils.GetLogInstance()
	db := mysqldao.GetDB(ctx)
	err := db.AutoMigrate(&IP{})
	if err != nil {
		logger.Error("InitIpTable error")
		os.Exit(1)
		return
	}
}

// SaveIp 保存数据到数据库
func SaveIp(ctx context.Context, ip *IP) {
	logger := utils.GetLogInstance()
	db := mysqldao.GetDB(ctx).Begin()
	ipModel := GetIpByProxyHost(ctx, ip.ProxyHost)
	if ipModel.ProxyHost == "" {
		err := db.Model(IP{}).Save(ip)
		if err.Error != nil {
			logger.Errorf("save ip: %s, error msg: %v", ip.ProxyHost, err.Error)
			db.Rollback()
		}
	} else {
		UpdateIp(ctx, ipModel)
	}
	db.Commit()
}

// GetIpByProxyHost 根据 proxyHost 获取一条数据
func GetIpByProxyHost(ctx context.Context, host string) *IP {
	logger := utils.GetLogInstance()
	db := mysqldao.GetDB(ctx)
	ipModel := new(IP)
	err := db.Where(IP{ProxyHost: host}).Find(ipModel)
	if err.Error != nil {
		logger.Errorf("get ip: %s, error msg: %v", ipModel.ProxyHost, err.Error)
		return nil
	}
	return ipModel
}

// CountIp 查询共有多少条数据
func CountIp(ctx context.Context) int64 {
	logger := utils.GetLogInstance()
	db := mysqldao.GetDB(ctx)
	var count int64
	err := db.Model(IP{}).Count(&count)
	if err.Error != nil {
		logger.Errorf("ip count: %d, error msg: %v", count, err.Error)
		return -1
	}
	return count
}

// GetAllIp 获取所有数据
func GetAllIp(ctx context.Context) []IP {
	logger := utils.GetLogInstance()
	db := mysqldao.GetDB(ctx)
	list := make([]IP, 0)
	err := db.Model(IP{}).Find(&list)
	ipCount := len(list)
	if err.Error != nil {
		logger.Warnf("ip count: %d, error msg: %v\n", ipCount, err.Error)
		return nil
	}
	return list
}

// GetIpByProxyType 根据 proxyType 获取一条数据
func GetIpByProxyType(ctx context.Context, proxyType string) ([]IP, error) {
	logger := utils.GetLogInstance()
	db := mysqldao.GetDB(ctx)
	list := make([]IP, 0)
	err := db.Where(IP{ProxyType: proxyType}).Find(&list)
	if err.Error != nil {
		logger.Errorf("error msg: %v\n", err.Error)
		return list, err.Error
	}
	return list, nil
}

// UpdateIp 更新数据
func UpdateIp(ctx context.Context, ip *IP) {
	logger := utils.GetLogInstance()
	db := mysqldao.GetDB(ctx).Begin()
	ipModel := ip
	ipMap := make(map[string]interface{}, 0)
	ipMap["proxy_speed"] = ip.ProxySpeed
	ipMap["update_time"] = utils.FormatDateTime()
	if ipModel.ProxyId != 0 {
		err := db.Model(IP{}).Where(IP{ProxyId: ipModel.ProxyId}).Updates(ipMap)
		if err.Error != nil {
			logger.Errorf("update ip: %s, error msg: %v", ipModel.ProxyHost, err.Error)
			db.Rollback()
		}
	}
	db.Commit()
}

// DeleteIp 删除数据
func DeleteIp(ctx context.Context, ip *IP) {
	logger := utils.GetLogInstance()
	db := mysqldao.GetDB(ctx).Begin()
	ipModel := ip
	err := db.Model(IP{}).Where(IP{ProxyId: ipModel.ProxyId}).Delete(ipModel)
	if err.Error != nil {
		logger.Errorf("delete ip: %s, error msg: %v", ipModel.ProxyHost, err.Error)
		db.Rollback()
	}
	db.Commit()
}

func RandomProxy(ctx context.Context) (ip IP) {
	logger := utils.GetLogInstance()
	ips := GetAllIp(ctx)
	ipCount := len(ips)
	if ipCount == 0 {
		logger.Warnf("RandomProxy random count: %d\n", ipCount)
		return IP{}
	}
	randomNum := utils.RandInt(0, ipCount)
	return ips[randomNum]
}

// RandomByProxyType .
func RandomByProxyType(ctx context.Context, proxyType string) (ip IP) {
	logger := utils.GetLogInstance()
	ips, err := GetIpByProxyType(ctx, proxyType)
	if err != nil {
		logger.Warn(err.Error())
		return IP{}
	}
	ipCount := len(ips)
	if ipCount == 0 {
		logger.Warnf("RandomByProxyType random count: %d\n", ipCount)
		return IP{}
	}
	randomNum := utils.RandInt(0, ipCount)
	return ips[randomNum]
}//考虑后面加随机数And根据权值
